﻿using BZ.Logger;
using HalconDotNet;
using NDK.Module.BLL;
using NDK.Module.Model;
using NDK.Motion.BLL;
using NDK.Motion.Monitor;
using NDK.Motion.StationLogic;
using System;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
using VisionPlatform;

namespace NDK.Module.StationLogic
{
    public class TrayLocation : StationLogic
    {
        #region 通用
        public override event PropertyChangedEventHandler PropertyChanged;
        private StationStep _curStep = StationStep.判断模式;
        public static TrayLocation Instance = new TrayLocation();
        private TrayLocation () : base()
        {
            this.Name = "Tray盘上料定位";
        }
        //步骤字段、属性
        private StationStep _step = StationStep.判断模式;
        [Monitor(Description = "当前步骤")]
        public StationStep Step
        {
            get
            {
                return _step;
            }
            set
            {
                if(_curStep != value)
                {
                    _step = value;
                    _curStep = value;

                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(value.ToString()));
                }
            }
        }
        #endregion

        /// <summary>
        /// 工站初始化
        /// </summary>
        public override void Init ()
        {
            base.Init();
            Step = StationStep.判断模式;
            logBaseInfo = "TrayLocation";

            CaptureImage1Count = 0;
            eng = new VisionManager.Engine("上料检测有无");
            CCD = Common.MVCameraList.getObject("TrayLoactionCCD");
        }


        public override void ActionProcess ()
        {
            try
            {
                switch(Step)
                {
                    case StationStep.判断模式:
                        if(Common.是否联机上料PLC)
                        {
                            Step = StationStep.流程开始;
                        }
                        break;

                    case StationStep.流程开始:
                        logCtStr = string.Empty;
                        swStepTime.Restart();
                        swStationCT.Restart();
                        logCtStr += $"{logBaseInfo},工位开始,{swStepTime.ElapsedMilliseconds},{Environment.NewLine}";
                        Step = StationStep.等待拍照;
                        break;

                    case StationStep.等待拍照:
                        if(Common.dic_plcComm_Bool["stPLC_PC.bCCD_Req_LD"])
                        {
                            CaptureImage1Count = 0;
                            Common.AppendUiLog.Log($"{logBaseInfo}:收到拍照请求", LogType.Info);
                            Step = StationStep.触发拍照;
                        }
                        break;

                    case StationStep.触发拍照:
                        CCD.Snap();
                        hImage_Cam = CCD.Image();
                        if(hImage_Cam == null)
                        {
                            CaptureImage1Count++;
                            if(CaptureImage1Count < 3)
                            {
                                Thread.Sleep(1000);
                                break;
                            }
                            else
                            {
                                if(AlarmPause("采图异常", "Tray盘上料定位相机连续三次采集异常：", "请检查相机是否掉线及相机参数是否存在异常", " 再次拍照", "忽略继续") == DialogResult.OK)
                                {
                                    CaptureImage1Count = 0;
                                    PublicMethod.ReconnectCam(ref CCD, "TrayLoactionCCD");
                                    break;
                                }
                            }
                        }
                        Step = StationStep.算法处理;
                        break;

                    case StationStep.算法处理:
                        if(StationManager.MachineProductionMode == RunningModeEnum.ProductionMode || StationManager.MachineProductionMode == RunningModeEnum.GRRMode)
                        {
                            if(!FixCamVisionResult("LayUpString", "Image0", hImage_Cam, 1))
                            {
                                if(AlarmPause("算法异常", $"Trayp盘上料定位算法异常，请检查", "上料定位算法异常，请检查", "重新计算", "忽略报警，继续运行") == DialogResult.OK)
                                {
                                    break;
                                }
                            }
                            if(hImage_Cam != null && Common.IsSaveImage)//存图
                            {
                                string childPath = DateTime.Now.ToString("yyyy-MM-dd") + "\\" + Common.CurProType;
                                string LocalPath = Common.picSavePath + "\\" + childPath + "\\" + DateTime.Now.ToString("yyyy-MM-dd");
                                PublicMethod.SaveImageWithBarCode(hImage_Cam, LocalPath, "上料1" + "-" + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss"));
                            }
                            Step = StationStep.拍照完成;
                        }
                        break;

                    case StationStep.拍照完成:
                        if(PLCWriteMethod(logBaseInfo, ("stPC_PLC.bCCD_Comp_LD", true, null)))
                        {
                            Step = StationStep.等待结束;
                        }
                        break;

                    case StationStep.等待结束:
                        if(!Common.dic_plcComm_Bool["stPLC_PC.bCCD_Req_LD"])
                        {
                            Common.AppendUiLog.Log($"{logBaseInfo}:拍照完毕", LogType.Info);
                            Step = StationStep.流程结束;
                        }
                        break;

                    case StationStep.流程结束:
                        if(StationManager.MachineProductionMode == RunningModeEnum.ProductionMode)
                        {
                            logCtStr += $"{logBaseInfo},上料定位工位结束,{swStepTime.ElapsedMilliseconds},{Environment.NewLine}";
                            logCtStr += $"{logBaseInfo},上料定位工位结束,{swStationCT.ElapsedMilliseconds},{Environment.NewLine}";
                            PublicMethod.WriteLogToTxt(logCtStr, $"000StepCT_{DateTime.Now:yyyyMMdd}", "上料定位工位");
                        }
                        Step = StationStep.判断模式;
                        break;
                }
            }
            catch(Exception ex)
            {
                UILog_Error($"[ TrayLocation ActionProcess Thread ERROR] {ex.Message}");
            }
        }

        public override void EmptyActionProcess ()
        {
            try
            {
                ActionProcess();
            }
            catch { }
        }

        public override void GRRActionProcess ()
        {
            try
            {
                ActionProcess();
            }
            catch { }
        }
        public enum StationStep
        {
            判断模式,
            流程开始,
            等待拍照,
            触发拍照,
            算法处理,
            拍照完成,
            等待结束,
            流程结束,
        }


        /// <summary>
        /// 获取相机算法结果
        /// </summary>
        /// <param name="FileName">算法流程文件名</param>
        /// <param name="outDataName">算法输出结果名称</param>
        /// <param name="listDataItems">输出的数据</param>
        /// <returns></returns>
        private bool FixCamVisionResult (string outDataName, string inputImageName, HImage InputImage, int inputFixtureID = 0)
        {
            try
            {
                eng.SetInputNumber("PanNum", inputFixtureID);
                eng.SetInputImage(inputImageName, InputImage);
                eng.ActionFun();
                var strResult = eng.GetOutputString(outDataName);
                string[] result = strResult.Trim().Split(';');
                if(strResult != "")
                {
                    for(int i = 0; i < result.Length - 1; i++)
                    {
                        _ = Machine.OmronPLC.Write($"stPC_PLC.stTrayExist_LD[{result[i].Substring(0, 3)}]", result[i][4] == '1');
                    }
                }
            }
            catch(Exception ex)
            {
                Common.AppendUiLog.Log($"上料检测有无算法流程异常" + ex.ToString(), LogType.Error);
                return false;
            }
            return true;
        }
    }
}
